{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "0a2bbe20-d9e4-4751-b11d-d3064d178960",
   "metadata": {},
   "source": [
    "# 线性方程、回归算法的评价指标"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e4c91a4f-007e-4193-8aba-12a08a49bd98",
   "metadata": {},
   "source": [
    "- 回忆回归问题的判定\n",
    "  - 目标值是连续性的值，而分类问题的目标值是离散的值\n",
    "- 回归处理的问题为预测\n",
    "  - 预测房价\n",
    "  - 销售额的预测\n",
    "  - 设定贷款额度\n",
    "  - 总结：上述案例中，可以根据事物的相关特征预测出对应的结果值\n",
    "- 线性回归在生活中的映射：生活案例【预测学生的期末考试成绩】\n",
    "  - 期末成绩的制定：0.7*考试成绩+0.3*平时成绩，则该例子中，特征值为考试成绩和平时成绩，目标值为总成绩。\n",
    "    - 回归算法预测出来的结果其实就是经过相关的算法计算出来的结果值\n",
    "    - 每一个特征需要有一个权重占比，这个权重占比明确后，则就可以得到最终结果，也就是获取了最终预测的结果了。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "e90ea6fb-edf3-4f0c-9e36-7bacb17033ad",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>面积</th>\n",
       "      <th>售价</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>55</td>\n",
       "      <td>110</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>76</td>\n",
       "      <td>152</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>80</td>\n",
       "      <td>160</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>100</td>\n",
       "      <td>200</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>120</td>\n",
       "      <td>240</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>150</td>\n",
       "      <td>300</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "    面积   售价\n",
       "0   55  110\n",
       "1   76  152\n",
       "2   80  160\n",
       "3  100  200\n",
       "4  120  240\n",
       "5  150  300"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "from pandas import DataFrame\n",
    "import matplotlib.pylab as plt\n",
    "\n",
    "# 现有一组售房的数据\n",
    "dic = {\n",
    "    '面积':[55,76,80,100,120,150],\n",
    "    '售价':[110,152,160,200,240,300]\n",
    "}\n",
    "\n",
    "df = DataFrame(data=dic)\n",
    "df"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fbb9380c-7424-4307-95d6-75c187aae4f8",
   "metadata": {},
   "source": [
    "- 需求对售房数据的分布情况进行展示"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "03818a47-a7a0-4525-898f-6ec5d97ae2aa",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.collections.PathCollection at 0x2951c0c2ed0>"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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/+IAtFheXp7ni9swjEYvsVRWVmr8+PEaO3asunTpopKSEs2YMUObNm1SeHi4NmzYoOLiYv3yl7+UYRhasGCBfvnLX3qFgsLCQh0/flwhISGN3jFVU1MjwzA0aNAgFRYWKjk5ucFxd955p6ZMmaJbbrml0X1zu92qqamRxWJRdHT09x6LsrIyxcTEfO84AK2HUAOgxQYPHqwvvvhCkrR+/XpNmDChwXFTpkxRcXGxXnjhBb388suSpKSkJCUlJckwDD3zzDOKjIzUL3/5Sx05ckRTpkzR0aNH9eKLL3pe480339RLL72kkJAQBQYGNvg+hmEoOjpadrtdX3/9tWdC73e98MILOn369Pfu34gRI7Ry5crvHVdUVKSqqir16NHje8cCaD3MqQHQ6p599ll98MEHnue6nOuNN97Q3r17Pbd2X3bZZXr55Zc1c+ZM5ebmesZlZ2erurpaZWVljd7t5HA4ZLfbVVlZqRMnTjQaamw2m957773zzsl54IEHFBIS0qT9W7FihRISEryeUAyg7XGmBkCTud1uvfTSS3rppZc8bd+dg3Luet0E2+7du3vmm5z7MLv9+/friSee0KuvvqqEhARP+8MPP6zFixfrF7/4hb744osmh4s6dXNeGgs1VqtVFRUVDT4wsE51dXWjl7nO/YXvEydO6IUXXtBDDz3UrBoBXHyEGgBN5nK59F//9V9ev3fUmN69ezf48LqqqiqdOXNGx44dU3p6uoYPH65HHnnEa4zFYlFOTo6uuuoqzZs3T4899tj3vt8333yjadOmqaamRmvWrFGvXr10+eWXNzi2pqZGDz300PcGkYZ+z0o6exxqa2v1zTffKCMjQ506ddLjjz9e7z2a+6vmAC4MoQZAk3366adNHlteXt5gu8PhUFVVlcLDw5WSkqI//OEPDY4bMmSIlixZ0miw+K7Y2FgdOnRIJ0+eVFpamh5//PFG5944HA699957GjNmTKOv9+CDD+r48eMN9p05c0ZVVVUqKytTQECAVqxY4bnNu47L5Wow1AFoPfxKN4AOx+FwKCwsrN7DBAG0b4QaAABgCtz9BAAATIFQAwAATIFQAwAATKHD3P3kdrt17NgxhYeHN/jbLgAAwP8YhqGysjL17Nmz0WdH1ekwoebYsWONPogLAAD4t6NHj6p3797nHdNhQk14eLikswclIiLCx9UAAICmcDqdiouL83yPn0+HCTV1l5wiIiIINQAAtDNNmTrCRGEAAGAKhBoAAGAKhBoAAGAKhBoAAGAKhBoAAGAKhBoAAGAKhBoAAGAKhBoAAGAKhBoAAGAKPn2i8KlTp7Rv3z71799fUVFRviwFAAC0UK3b0Bb7SR0vq1JMeKhS4qMVGND2Px7tszM1S5cuVZ8+fTRu3Dj17t1bS5culSTl5+crOTlZUVFRysrKkmEYnm0+/fRTDRgwQN26ddPs2bN9VToAAPi31flFuv7ltcpcuFn/+ZcvlLlws65/ea1W5xe1eS0+CTUOh0MPP/ywNmzYoF27diknJ0dZWVlyuVzKyMjQ0KFDtXXrVhUUFGjRokWSpBMnTmjkyJHKzMxUbm6uFi9erHXr1vmifAAAoLOBZuL721XkqPJqL3ZUaeL729s82Pgk1DidTs2ZM0eDBg2SJF155ZX69ttvtWrVKjkcDs2ePVsJCQmaPn263nrrLUnS4sWL1bNnTz3zzDPq16+fnn32WU8fAABoW7VuQ9NWFMhooK+ubdqKAtW6GxrROnwSauLi4nTvvfdKkmpqavT73/9eo0aNUl5enlJTUxUWFiZJGjRokAoKCiRJeXl5GjZsmOdXOlNSUrRt27ZG38PlcsnpdHotAADg4thiP1nvDM25DElFjiptsZ9ss5p8evdTXl6eunfvrtWrV+u1116T0+lUfHy8p99isSgwMFClpaX1+iIiInTs2LFGX3vGjBmy2WyeJS4urlX3BQCAjuR4WeOBpiXjLgafhppBgwbp448/Vr9+/TRu3DhZrVaFhIR4jQkNDVVFRUW9vrr2xkydOlUOh8OzHD16tNX2AwCAjiYmPPSijrsYfBpqLBaLhg4dqnfeeUf/+Mc/FB0drRMnTniNKSsrU3BwcL2+uvbGhISEKCIiwmsBAAAXR0p8tHrYQtXYjdsWST1sZ2/vbis+CTWffvqpsrKyPOvBwcGyWCwaMGCAcnNzPe12u10ul0vR0dFKTk726tuxY4d69erVpnUDAICzAgMsys5IlKR6waZuPTsjsU2fV+OTUNO/f38tWLBACxYs0NGjR/Xkk0/qlltu0YgRI+R0OvX2229LkqZPn67hw4crMDBQI0eO1KZNm/TJJ5+opqZGr7zyim699VZflA8AACSlDeyh+WOuVHeb9yWm7rZQzR9zpdIG9mjTeizGuU+3a0Nr1qzRr3/9ax09elS33nqr5s2bp0suuUQfffSRMjMz1alTJwUEBGj9+vVKTDybBF9//XVNnjxZXbp0UWRkpHJzcxUbG9uk93M6nbLZbHI4HFyKAgDgImrNJwo35/vbZ6HmfIqLi7Vt2zalpqaqa9euXn12u1179+7VDTfcoC5dujT5NQk1AAC0P+0+1LQGQg0AAO1Pc76/+ZVuAABgCoQaAABgCoQaAABgCoQaAABgCoQaAABgCoQaAABgCoQaAABgCoQaAABgCoQaAABgCoQaAABgCoQaAABgCoQaAABgCoQaAABgCoQaAABgCoQaAABgCoQaAABgCoQaAABgCoQaAABgCoQaAABgCoQaAABgCoQaAABgCoQaAABgCoQaAABgCoQaAABgCoQaAABgCoQaAABgCoQaAABgCoQaAABgCoQaAABgCoQaAABgCoQaAABgCoQaAABgCj4LNcuXL1ffvn1ltVqVlJSkPXv2aNGiRbJYLPWWRYsWSZJGjhzp1T58+HBflQ8AAPyMxTAMo63f9ODBg0pOTtbrr7+um266SY8++qgKCwu1bt06VVRUeMaVl5dryJAh2rx5sxISEtSzZ099/PHH6t27tyQpKChInTt3btJ7Op1O2Ww2ORwORUREtMp+AQCAi6s539/WNqrJy549ezRz5kzdddddkqSJEyfqtttuU3BwsIKDgz3j5s2bp1GjRikhIUGFhYUyDEMDBw70RckAAMDP+STUpKene63v27dP/fr182qrqqrS3Llz9dlnn0mStmzZotraWvXu3VulpaXKyMjQ/PnzFRUV1eB7uFwuuVwuz7rT6bzIewEAAPyJzycKV1dXa9asWZowYYJX+5IlS3T11VerT58+kqS9e/dq8ODBWrlypTZv3iy73a6pU6c2+rozZsyQzWbzLHFxca25GwAAwMd8MqfmXFOnTtWqVav0+eefKygoyNOekpKi5557TiNGjGhwuw0bNujOO+9USUlJg/0NnamJi4tjTg0AAO2I38+pqbN27Vrl5ORo8+bNXoHmwIEDOnDggG6++eZGt42JidG3334rl8ulkJCQev0hISENtgMAAHPy2eUnu92uzMxM5eTkKDEx0avvgw8+UHp6ulfQ+fnPf66NGzd61nNzcxUbG0twAQAAknwUaiorK5Wenq7bb79do0aNUnl5ucrLy1V3JWz16tX68Y9/7LXNj370Iz322GPauHGjli1bpqlTp2rixIk+qB4AAPgjn8ypWb58ue6444567Xa7XbGxsYqMjFReXp5+8IMfePpqamo0YcIE/fWvf1V4eLgmTpyoJ598UlZr066g8ZwaAADan+Z8f/t8onBbIdQAAND+NOf72+e3dAMAAFwMhBoAAGAKhBoAAGAKhBoAAGAKhBoAAGAKhBoAAGAKhBoAAGAKhBoAAGAKhBoAAGAKhBoAAGAKhBoAAGAKhBoAAGAKhBoAAGAKhBoAAGAKhBoAAGAKhBoAAGAKhBoAAGAKhBoAAGAKhBoAAGAKhBoAAGAKhBoAAGAKhBoAAGAKhBoAAGAKhBoAAGAKhBoAAGAKhBoAAGAKhBoAAGAKhBoAAGAKhBoAAGAKhBoAAGAKhBoAAGAKhBoAAGAKhBoAAGAKPgs1y5cvV9++fWW1WpWUlKQ9e/ZIkiZPniyLxeJZLr/8cs82+fn5Sk5OVlRUlLKysmQYhq/KBwAAfsYnoebgwYMaO3asZs6cqcLCQvXv31/jxo2TJG3dulUrV65UaWmpSktLtWPHDkmSy+VSRkaGhg4dqq1bt6qgoECLFi3yRfkAAMAPWQwfnO745z//qWPHjmn8+PGSpHXr1um2226T0+lU165dVVhYqC5dunhts2zZMv3iF7/Q119/rbCwMOXl5emRRx7Rxo0bm/SeTqdTNptNDodDERERF32fAADAxdec729rG9XkJT093Wt937596tevn3bt2iW3262kpCQVFhbqpptu0oIFC3TppZcqLy9PqampCgsLkyQNGjRIBQUFjb6Hy+WSy+XyrDudztbZGQAA4Bd8PlG4urpas2bN0oQJE1RQUKArrrhC7733nnbu3Cmr1eo5m+N0OhUfH+/ZzmKxKDAwUKWlpQ2+7owZM2Sz2TxLXFxcm+wPAADwDZ+cqTlXdna2OnfurHHjxikoKEj33nuvp2/evHmKj4+X0+mU1WpVSEiI17ahoaGqqKhQVFRUvdedOnWqHn/8cc+60+kk2AAAYGI+DTVr165VTk6ONm/erKCgoHr9MTExcrvdKioqUnR0tPLz8736y8rKFBwc3OBrh4SE1AtBAADAvHx2+clutyszM1M5OTlKTEyUJGVlZWnJkiWeMbm5uQoICFBcXJySk5OVm5vrtb3L5VJ0dHSb1w4AAPyPT87UVFZWKj09XbfffrtGjRql8vJySWcn/z799NOKjY1VbW2tHn30Ud1///0KCwvTjTfeKKfTqbfffltjx47V9OnTNXz4cAUGBvpiFwAAgJ/xyS3dy5cv1x133FGv3W6364033tD8+fMVGBioMWPGaPr06ercubMk6aOPPlJmZqY6deqkgIAArV+/3nOW5/twSzcAAO1Pc76/fRJqLkRxcbG2bdum1NRUde3atcnbEWoAAGh//P45NReie/fuuu2223xdBgAA8DM+f04NAADAxUCoAQAApkCoAQAApkCoAQAApkCoAQAAptDu7n4CALSOWrehLfaTOl5WpZjwUKXERyswwOLrsoAmI9QAALQ6v0jTVhSoyFHlaethC1V2RqLSBvbwYWVA03H5CQA6uNX5RZr4/navQCNJxY4qTXx/u1bnF/moMqB5CDUA0IHVug1NW1Gghh4tX9c2bUWBat3t6uHz6KAINQDQgW2xn6x3huZchqQiR5W22E+2XVFACxFqAKADO17WeKBpyTjAlwg1ANCBxYSHXtRxgC8RagCgA0uJj1YPW6gau3HborN3QaXER7dlWUCLEGoAoAMLDLAoOyNRkuoFm7r17IxEnleDdoFQAwAdXNrAHpo/5kp1t3lfYupuC9X8MVfynBq0Gzx8DwCgtIE9dHNid54ojHaNUAMAkHT2UtQ1CV19XQbQYlx+AgAApkCoAQAApkCoAQAApkCoAQAApkCoAQAApkCoAQAApkCoAQAApkCoAQAApkCoAQAApkCoAQAApkCoAQAApkCoAQAApkCoAQAApkCoAQAApkCoAQAApuCzULN8+XL17dtXVqtVSUlJ2rNnz3nbJWny5MmyWCye5fLLL/dV+QAAwM/4JNQcPHhQY8eO1cyZM1VYWKj+/ftr3LhxjbbX2bp1q1auXKnS0lKVlpZqx44dvigfAAD4IYthGEZbv+k///lPHTt2TOPHj5ckrVu3Trfddps++OCDBtsrKip05swZde3aVYWFherSpUuz39PpdMpms8nhcCgiIuKi7g8AAGgdzfn+trZRTV7S09O91vft26d+/fo12i5Ju3btktvtVlJSkgoLC3XTTTdpwYIFuvTSSxt8D5fLJZfL5Vl3Op0XeS8AAIA/8flE4erqas2aNUsTJkw4b3tBQYGuuOIKvffee9q5c6esVqvnjE5DZsyYIZvN5lni4uJadT8AAIBv+eTy07mmTp2qVatW6fPPP1dQUND3ttc5cuSI4uPjVVpa2uDpqIbO1MTFxXH5CQCAdsTvLz/VWbt2rXJycrR582av4NJY+7liYmLkdrtVVFTU4E6GhIQoJCSk1WoHAAD+xWeXn+x2uzIzM5WTk6PExMTvbc/KytKSJUs867m5uQoICOCyEgAAkOSjMzWVlZVKT0/X7bffrlGjRqm8vFySFBgY2GB7586dNXjwYD399NOKjY1VbW2tHn30Ud1///0KCwvzxS4AAAA/45M5NcuXL9cdd9xRr33OnDn69a9/Xa/dbrerT58+mjp1qubPn6/AwECNGTNG06dPV+fOnZv0ntzSDQBA+9Oc72+fTxRuK4QaAADan+Z8f/v8lm4AAICLgVADAABMgVADAABMgVADAABMgVADAABMgVADAABMgVADAABMgVADAABMgVADAABMgVADAABMgVADAABMgVADAABMgVADAABMgVADAABMgVADAABMgVADAABMgVADAABMocWhxu12X8w6AAAALkiLQs1nn32m66+/XoZhXOx6AAAAWqTZoaampkaTJk3SddddJ4vF0ho1AQAANJu1uRuMGzdOMTExuuWWW3T99dcrODjYq98wDLlcLv3f//3fRSsSAADg+zQp1Jw5c0anTp3SuHHj1LlzZ3344YcqKSnRb3/7WwUFBXmNdbvdcrlcrVIsAABAY5oUat544w1lZWVp0qRJeuWVVyRJPXv2VM+ePVu1OAAAgKZqUqjJyMhQcXGx3njjDfXo0UOPPfaYTp48qby8PPXs2VMxMTGKiopq7VoBAAAaZTGacQvT8ePHNX78eJ05c0a//e1vlZWVperqajmdTpWWluraa6/V008/rZSUlNasuUWcTqdsNpscDociIiJ8XQ4AAGiC5nx/N+vup5iYGH344YeKiYnR3LlztWnTJm3btk1ffvmlCgsLNWLECN1yyy2aP3/+Be0AAABAczUp1GzZskU7d+6UJFksFi1cuFDl5eXas2ePZ0xISIgmTJigVatWacOGDa1TLQAAQCOaNKfm448/1vTp03XNNdfozjvvVFBQkO644w5t2rRJmzZt8hprGIauvfbaVikWAACgMU2eU3P69Gm9++67mjNnjg4cOKAbb7xRQ4YMqfdU4aqqKtXU1OjNN99slYJbijk1AAC0P835/m7WRGHp7DNr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",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib.pyplot as pyt\n",
    "pyt.rcParams['font.sans-serif']='SimHei'\n",
    "pyt.rcParams['axes.unicode_minus']=False\n",
    "\n",
    "pyt.title('面积与售价')\n",
    "pyt.xlabel('面积')\n",
    "pyt.ylabel('售价')\n",
    "pyt.scatter(df['面积'],df['售价'])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c44a117a-5de4-429e-9866-7a5bc5f7b906",
   "metadata": {},
   "source": [
    "- 问题：假如现在有一套房子，面积为76.8平米，那么这套房子应该卖多少钱，也就是如何预测该套房子的价钱\n",
    "  - 上图中散点的分布情况就是面积和价钱这两个值之间的关系，那么如果该关系可以用一个走势的直线来表示的话，那么是不是就可以通过这条线走势的直线预测出新房子的价格"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "a514d053-6046-4453-b10f-fa6de4d187c5",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.collections.PathCollection at 0x2951c0f2450>"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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d955Z8B6Jt+WEK0DGkB+7ydOnAhAdmA+la5eM2rUKNxxxx1ISUnBd999h5tuuumUryPqaxjQEPVhjz/+ON5//33Ex8e3Offqq69i3759WL58OQBgyJAh+J//+R88++yzyMnJ8V/X0NCAhx9+uN2OxEDzvlB79uyBzWaDzWbDpZdeesr9omw2G7Zu3XrKxbXtOXToEMaPH4/CwkL/sffeew9utxsDBgzAggULAKDddNiRI0f8j9brSxRFwbhx4/zjA9oPaI4dO4bp06fDarVi8eLFAef2798PAO0GNC11tm/Tpk2b8Mgjj+CLL75o87Pzer0Bz1UqFf7+979j8uTJeOGFF3Duuedi5cqVbd6zK8ERUThjyokoDDQ1NeGZZ57BM8884z/Wclag9XPfL6+kpCT/DErLAOPAgQP4zW9+gz/+8Y8YPny4//h9992HVatW4c4778SuXbug0+nwhz/8wf9+vl+mLX+p+n4xm0wmWCwWAHJdSOuFxa1/ES9evBjJycm45JJLuvx9qKysRGFhIaZMmYKFCxciPj4ea9aswcsvv4z9+/fjvffew6JFi/D000/jkUcewZgxY7BixQpceuml/ntITU0NeM/W64V89u7dC51OF7Aot76+Hm+//TYee+wxRERE4PPPP0d0dDQA4KuvvsKGDRvw8ccfIy4uLuD72p7WAY1vfEIIRERE4Pnnn8cll1yCu+66K+C6xsZGNDU14dChQ/5jkZGRuPXWWzF//nx8/vnnGDdunP98UVGR/3Xc/oD6tF7tekNEZ2Ty5MnioYce6rAzcMtHZGSk+Nvf/tbmPe677z4xb948UVRUJNLS0sT111/f7tfasWOHUKlUYunSpW3O+bY52Ldvn/+Y2+0WX3/9dUBX3MrKSuFwOAJe6+sofPDgQfH4448LRVHEp59+GnDN+++/L8xmc4ffhyuuuEKoVCqxfPlyIYQQt9xyi1AURcyfP9/fXfirr74Ser1eXHjhhcJqtQqbzSaEEOKzzz5rt7Heb3/7W//zo0ePiv/3//6fWLBggYiNjRU//elPA65/9913haIoYt68eW22nTh69Kgwm81i2rRpYuvWrR3eQ0daNtZramoSjY2N7V63atWqM9o6oXXTQKK+hgENUT8xb948MWfOHOFwOMS8efNEVVVVh9e+99577e5FdDaKiooEALFr1y5x++23i5de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RVJSUrCH0+2uuOIK8dJLLwX8Bd/Zz/mFF14Q55xzjmhqahJCCLF27Voxb968oIz9bLR33x193oXo+DMRjtq7987ury997tu799Z8n3khRFh87hnQnIUnn3xS/PSnP/U/b2pqEjExMUEcUe955ZVXxNixY8WOHTtEVFSUGD58uNDr9WLGjBni6NGjwR5et+no/vrbz97lcomEhARRUFAg/vGPf4j4+HgxcOBAYTQaxU033SSqqqqCPcSz9uOPPwohRMBf8J39nO+44w5x7733+s8VFxeLc845p/cG3E3au+/WfJ93ITr+TISj9u69s/vrS5/7U/3cW37mhRBh8bnnGpqz4HA4kJqa6n+uKArUajVsNlsQR9Xz6uvr8fzzz+Oee+5Bfn4+Ro4cibfffhs//PADNBoN7r777mAPsdt0dH/97We/evVqXHTRRRg6dCj27duHcePGYf369fj2229RUFCAxYsXB3uIZ63lz9Ons59z63MmkwnFxcW9Mtbu1N59t9Ty8w50/JkIR+3de2f315c+96f6ubf8zAMIj899sCOqcPab3/xG/PrXvw44NmjQIHH8+PEgjah3PPzww2LcuHGivr6+zbmjR48KlUol7HZ7EEbW83z396tf/apf/ewzMzPF+vXr2z335ZdfitjY2F4eUc9Bi3+xdvYZv/HGG8VLL73kP97Y2Cg0Gk1vDrVboYN/qXf2eReib3zmO7p3IQLvry/+nd/RvXf2mRciND/3nKE5C1arFeXl5QHHnE4ntFptkEbU8zZt2oRly5Zh9erViIiIaHM+ISEBTU1NOHHiRBBG1/N895eUlNRvfvaHDh3CoUOHcOWVV7Z7PiEhAZWVlfB4PL08sp7X2We89bm++PM/1ecd6D+f+RMnTvSbv/NP9ZkHQvNzz4DmLGRmZiInJ8f/vKCgAB6PB1arNYij6jkFBQWYO3culi1bhtGjRwMAsrKysHr1av81OTk5UKlUSElJCdYwu1VH93feeef1m5/9+++/j2uuucb/C+2mm27CN9984z+fk5ODxMTEsNrzpas6+4y3Prdz504MHDgwGMPsEe193oH++5lPSUnpN3/nt/7MA2HyuQ/2FFE4a2hoEPHx8f6yvYULF4prrrkmyKPqGXV1dWL06NHiv//7v4XT6fQ/3nrrLZGamio+//xz8emnn4r09HRxxx13BHu43ebtt99u9/76089+0qRJ4o033vA/f/rpp8UFF1wgvv76a7FmzRqRmJgonnzyySCOsHuhVcVLRz/n8vJyodfrxWeffSbq6+vFVVddJR544IFgDfustbzvjj7vTU1NHX4mwlnLe+/s/vri5x7tpJxaf+aFCI/PPQOas7Ru3TphNBpFbGysiI+PF3v27An2kHrE2rVrBYA2j4KCAvHwww8Ls9ksrFarWLRoUcj1JjhbHd1ff/jZ19XVCa1WK/bu3es/Vl9fL+68804RGRkpkpKSxFNPPSUaGhqCOMru1fov+M5+zq+88oqIiIgQMTExIjU1VZSUlARhxN2j5X139nkXouPPRLhq/TPv7P762ue+9b2395kXIjw+99xtuxuUlJRg+/btmDhxImJjY4M9HOpF/Nn3D539nAsKCrBv3z5MmjQJUVFRQRoh9SZ+7kMTAxoiIiIKe1wUTERERGGPAQ0RERGFPQY0REREFPYY0BBRyBFCwOVyoStL/HzXElH/pgn2AIiIWisuLkZaWhoMBgMURQEgA5eqqipYrVb/MQBoampCQkIC9u3bBwCoq6vD7t278fnnn0NRFDzyyCNBuQci6l2sciKisLBz505cf/31OHLkSLvnv/vuO/zsZz+DEALFxcV46qmncOmll+K7777Ds88+i5iYGP+1R48eRXV1Ncxmcy+Nnoh6GgMaIgoLzz77LEpKSvDiiy+2e76pqQk1NTUwmUzQ6/Vwu90AgKVLl6KsrAzPPvus/1pFUVBXVweDwdAbQyeiXsCUExGFpAMHDmD69On+5xUVFdDr9Vi7dm3AddHR0di9eze8Xi8MBoN/3Y0QAg0NDVCp2l8q2DJtRUThj4uCiSgkKYoCt9uNI0eOYOXKlbjqqqtQUVGBI0eOoLGxEfv27cOWLVv8uzz/4Q9/gMViQXR0NDweDywWCywWC+x2e5DvhIh6AwMaIgpJLXf6BYDPPvsMY8aMwZgxY1BaWuo/rtHIieannnoKtbW1+OMf/wgAKCwsRF1dHYxGY7vv7/V6e2jkRBQMDGiIKCxceeWVyMvLQ15eHhITE9u9pr6+HsuWLYNKpcIll1yCLVu2wOPx4MUXX/TP2FgsFv+1RNR3cA0NEfUZv//97zFlyhQcOnQI//u//4sHH3wQ27dvxz333IO4uDgAQGNjo39Wh4j6Ds7QEFFY6Cjl5PO3v/0NK1euxO9//3sAwFVXXYXNmzfD5XJhwoQJ2LRpExobGzF+/Hhs2bKll0dPRD2NAQ0RhYVTpZwuvfRSrFmzBrGxsf5jJpMJv/3tb5GRkYHLL78cGo0Gv/vd73DjjTfi+PHjvTl8Iuph7ENDRCHpxx9/RFpaGgYMGACPx4Pa2lpYrVYAQElJCZKSkuD1etHU1NRmxkaj0aC+vh6vvfYaXn75ZeTk5AQ00bvjjjtw+PBhbN68meknoj6Cn2QiCkkejwfx8fGdzqQcOXIE48ePDzhWW1sLr9eL6upqfPzxx/joo4/adAR+8cUX8fLLL8Pr9TKgIeojOENDREREYY9raIiIiCjsMaAhIiKisMeAhoiIiMIeAxoiIiIKewxoiIiIKOwxoCEiIqKwx4CGiIiIwh4DGiIiIgp7DGiIiIgo7DGgISIiorD3/wFUtqGemoVN1gAAAABJRU5ErkJggg==",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.scatter(df['面积'],df['售价'])\n",
    "plt.xlabel('面积')\n",
    "plt.ylabel('售价')\n",
    "plt.title('面积和价钱的分布图')\n",
    "plt.scatter(np.linspace(0,180,num=100),np.linspace(0,360,num=100),alpha=0.3)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1b6497e2-4417-42ed-95d7-3014120e3183",
   "metadata": {},
   "source": [
    "- 散点的趋势：\n",
    "  - 在上图中使用了一条直线来表示房子的价格和面积对应的分布趋势，那么该趋势找到后，就可以基于该趋势根据新房子的面积预测出新房子的价格\n",
    "- 线性回归的作用：\n",
    "  - 就是找出特征和目标之间存在某种趋势，在二维平面中，该种趋势可以用一条线段来表示\n",
    "- 该趋势使用什么表示 --》线性方程：\n",
    "  - 在数学中，线性方程y = wx就可以表示一条唯一的直线。那么在上述售房数据中，面积和价格之间的关系，其实就可以映射成：\n",
    "    - 价格 = 2*面积 ==》 y=2x，这个方程就是价格和面积的趋势，也就是说根据该方程就可以进行新房子价格的预测\n",
    "  - 标准的线性方程式为：y=wx+b，w为斜率，b为截距。那么如果用线性方程表示房价和面积的趋势的化，这个b是否需要带上\n",
    "    - b(截距)=0:直线会经过原点\n",
    "    - b!=0:直线会经过b点\n",
    "  - 是否带上b，需要具体情况具体分析。y=wx，如果x=0，则y必定为0，那就意味着趋势对应的直线必过原点，如果带上b值，则直线不过原点。如果上有图的趋势直线过原点，趋势则会不准。加b的目的是为了使得趋势对应的直线更加具有通用性\n",
    "    - 如果目标值可能为0的话，就带上b，反之不带"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c047ee80-a1ec-49f1-a990-fbd83d41ec30",
   "metadata": {},
   "source": [
    "- 上述的线性方程y=wx+b其中x为特征为目标，这种方程作为线性关系模型的预测依据的话是否可以满足所有的预测场景\n",
    "  - 如果现在房价受影响的因素不光是面积，加入了采光率和楼层，那么就意味着特征变成了3种。在原始的线性方程y=wx+b中只有一个特征，则该方程不具备通用性。\n",
    "  - 标准线性关系模型为：\n",
    "    - 售价 = (w1面积+w2采光率+w3楼层) + b==》y=(w1x1+w2x2+wnxn)+b\n",
    "    - w又叫做权重\n",
    "    - b可以变换成w0*x0,x0=1\n",
    "      - y=w0x0+w1x1+w2x2+wnxn\n",
    "    - 权重向量(行向量):w0,w1,...wn\n",
    "      - 行向量的转置就是列向量。行向量是一个n*1的矩阵，即矩阵有一个含有n个元素的行所组成。\n",
    "    - 行向量乘以行向量的转置为一个常数\n",
    "\n",
    "Y=XWT(T为转置)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6ec50cc5-8daf-4afa-a763-6ffdb23fb2a5",
   "metadata": {},
   "source": [
    "- 如果房价预测案例中，特征与目标之间的分布规律不是线性的，那么是否还可以使用一条直线表示特征和目标之间的趋势\n",
    "  - 可以，只要保证直线距离所有散点最近，则该直线还是可以在一定程度上表示非线性分布散点之间的分布规律。但是该规律会存在误差"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "02c4abed-589d-44eb-91ab-823db4b9a026",
   "metadata": {},
   "source": [
    "- 误差存在，在处理误差之前，必须要知道一个回归算法的特性：\n",
    "  - 回归算法是一个迭代算法。所谓的迭代就是像系统版本的迭代，迭代后的系统要比迭代前的系统更好\n",
    "    - 当开始训练线性回归模型的时候，是逐步的将样本数据带入模型对其进行训练\n",
    "    - 训练开始时先用部分的样本数据训练模型生成一组w和b，对应的直线和数据对应散点的误差比较大，通过不断的带入样本数据训练模型会逐步的迭代不好(误差较大)的w和b从而使得w和b的值更加精准。\n",
    "  - 官方解释：迭代是重复反馈过程的活动，其目的是为了逼近所需目标或结果。每一次对过程的重复称为一次迭代，而每一次迭代得到的结果会作为下一次迭代的初始值。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "516c4e56-fa28-4c0a-b8a7-9b69aa7b7e06",
   "metadata": {},
   "source": [
    "- 误差的处理方法：\n",
    "  - 通俗来说，回归算法就是不断的自身迭代的减少误差来使得回归算法的预测结果可以越发逼近真实结果"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ee27f3f7-a942-4736-b031-a4c57fb4b361",
   "metadata": {},
   "source": [
    "- 如何不断迭代的减少误差\n",
    "  - 通过【损失函数】来表示误差\n",
    "  - (hw(x1)-y1)^2+(hw(x2)-y2)^2+...+(hw(xm)-yM)^2\n",
    "    - hw(xi):预测值\n",
    "    - yi:为第i个训练样本的真实值"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "967581b9-5f98-4110-8308-71b3927c3aae",
   "metadata": {},
   "source": [
    "- 损失函数也可表示：\n",
    "$$\\sum_{i=1}^{m}{i}   (y_i-X_iw)^2$$"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "258cb169-deb0-4d43-b9eb-8290237da90a",
   "metadata": {},
   "source": [
    "- 因此得知误差的大小线性回归方程中的系数w是有直接关系的\n",
    "  - w（权重）的不同会导致误差大小的不同\n",
    "  - 那么最终的问题就转化为了：如何去求解方程中的w使得误差最小化"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ec1be6c4-0919-4348-81e7-80748e324907",
   "metadata": {},
   "source": [
    "- L0,L1和L2范式：\n",
    "  - L0是指向量中非0的元素的个数\n",
    "  - L1是指向量中各个元素绝对值之和\n",
    "  - L2是指向量各元素的平方和然后求平方根\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ff1a8924-ce97-4b44-9924-b9898df77664",
   "metadata": {},
   "source": [
    "- L2范式：\n",
    "  - 这个损失函数代表了向量yi-y^i的L2范式的平方结果，L2范式的本质就是欧氏距离，即两个向量上的每个点对应相减后的平方再开平方，我们现在只实现了向量上每个点对应相减后的平方和，并没有开方，所以我们的损失函数是L2范式，即欧式距离的平方结果"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7d83be95-9a1c-4231-aeef-400885b5160a",
   "metadata": {},
   "source": [
    "((xi-yi)^2)^1/2  =  min||y-Xw||2  (L2范式)\n",
    "\n",
    "                     w"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cd5293a3-eb7a-4ce4-8d8c-df76fbb82b23",
   "metadata": {},
   "source": [
    "- 在这个平方的结果下，我们的y和y^分别是我们的真实标签和预测值，也就是说，这个损失函数实在计算我们的真实标签和预测值的距离。因此，我们认为这个损失函数衡量了我们构造的模型的预测结果和真实标签的差异，因此我们固然希望我们的预测结果和真实值差异越小越好。所以我们的求解目标就可以转化为：\n",
    "\n",
    "$$min_w||y-Xw||_2 ^2$$"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6821bcb2-2233-44f9-8f4f-da31ed8ad3af",
   "metadata": {},
   "source": [
    "- SSE&RSS:\n",
    "  - 其中右下角的2表示向量y-Xw的L2范式,也就是我们的损失函数所代表的含义。再L2范式上开平方，就是我们的损失函数。我们往往称呼这个式子为SSE(Sum of Sqaured Error,误差平方和)或者RSS(Residual Sum of Squares 残差平方和)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fd15e39f-d35e-4043-9860-970a6afee80b",
   "metadata": {},
   "source": [
    "- 最小二乘法\n",
    "  - 现在问题转换成了求解让RSS最小化的参数向量w,这种通过最小化真实值和预测值之间的RSS来求解参数的方式叫做最小二乘法。\n",
    "  - 求解极值(最小值)的第一步往往是求一阶导数并让一阶导数等于0，最小二乘法也不能免俗。因此，我们现在再残差平方和RSS上对参数向量w求导。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "78cf794b-0e63-4665-aaf3-3d4e017f218e",
   "metadata": {},
   "source": [
    "- 首先w表示的是一个列向量(矩阵)，我们现在并非是对常数求导，而是对列向量（矩阵）进行求导。矩阵求导的自行掌握即可。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "23410f14-d77a-4ebb-a8ce-5a57c73192e4",
   "metadata": {},
   "source": [
    "- 首先将L2范式拆开：\n",
    "\n",
    "$$\\frac{∂RSS}{∂w}=\\frac{∂||y-Xw||_2^2}{∂w}=\\frac{∂(y-Xw)^T(y-Xw)}{∂w}$$\n",
    "\n",
    "- 两个向量(y&Xw)的平方和就等于两个向量的转置乘以两个向量的本身"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cbe40d90-3b54-4578-ac24-54ce168503e8",
   "metadata": {},
   "source": [
    "- 处理转置乘法和减法\n",
    "$$因为(A-B)^T=A^T-B^T并且(AB)^T=B^T*A^T$$\n",
    "$$所以 \\frac{∂(y^T-w^TX^T)(y-Xw)}{∂w}$$"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ae2001c7-13cf-4bd9-bc23-f027b6a4f4dc",
   "metadata": {},
   "source": [
    "- 然后将上图的分子进行多项式相乘：\n",
    "$$= \\frac{∂(y^Ty-w^TX^Ty-y^TXw+w^TX^TXw)}{∂w}$$\n",
    "\n",
    "$$= \\frac{∂y^Ty-∂w^TX^Ty-∂y^TXw+∂w^TX^TXw}{∂w}$$"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "241b2d9a-204d-481d-a182-4673a3e46c6e",
   "metadata": {},
   "source": [
    "- 然后公式就变相为yTy对w的求导，wTXTy对w的求导,yTXw对w的求导,wTXTXw对w的求导。这里的w为列向量(矩阵)则就涉及到对矩阵的求导：\n",
    "  - 再矩阵求导中如果小a为常数项，A为矩阵则：\n",
    "    $$\\frac{∂a}{∂A}=0，\\frac{∂A^TB^TC}{∂A}=B^TC，\\frac{∂C^TBA}{∂A}=B^TC，\\frac{∂A^TBA}{∂A}=(B+B^T)A$$\n",
    "    - 由于y是一个列向量，为一阶矩阵，那么其本身乘以其转置为一个常数"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bd774f2d-8635-47a4-bc4d-ab7dd7d124ef",
   "metadata": {},
   "source": [
    "- 分子上的每一项对w进行求导后的结果为：\n",
    "  $$= 0-X^T-X^Ty+2X^TXw$$\n",
    "  $$= X^TXw-X^Ty$$\n",
    "  - 至此我们就求解出了对w求导的一阶导数，接下来让一阶导数为0则就求出最小误差下的w的值了"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "26f88ee4-7d69-4623-9291-eca1269b8e29",
   "metadata": {},
   "source": [
    "$$X^TXw-X^T=0$$\n",
    "$$X^TXw=X^Ty$$\n",
    "$$左乘一个(X^TX)^-1 则有:$$\n",
    "$$w=(X^TX)^-1X^Ty$$X^TXw-X^T=0$$$$"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3da101e9-7635-4bf2-86d7-9fdf3340f2ab",
   "metadata": {},
   "source": [
    "- -1表示逆矩阵，矩阵*自己的逆矩阵=1"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e0650645-6a01-4fc7-88f0-dcc70502e54e",
   "metadata": {},
   "source": [
    "- API\n",
    "  - 最小二乘(正规方程):from sklearn.linear_model import LinearRegression\n",
    "  - 参数：\n",
    "    - fit_intercept 是否带截距（默认带）\n",
    "    - normalize 原始样本归一化处理(默认关)，如果为True，则特征矩阵X再进入回归之前将会被减去均值(中心化)并除以L2范式(缩放)。如果希望进行标准化，请在fit数据之前使用preprocessing模块中的标准化专用类StandadScaler\n",
    "    - copy_X 默认为True:如果为真，将在X.copy()上进行操作，否则的话原本的特征矩阵X可能被线性回归影响并覆盖\n",
    "    - n_jobs  默认为None :用于计算作业数。旨在多标签的回归和数据量足够大的时候生效。除非None再joblib.parallel_backend上下文中，否则None统一表示为1，如果输入-1，则使用全部的CPU来进行运算"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "3a4ba653-18a8-4eb1-84ad-f2cdb94e32af",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "((442, 10), (442,))"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import sklearn.datasets as datasets\n",
    "diabetes = datasets.load_diabetes()\n",
    "feature = diabetes['data']\n",
    "target = diabetes['target']\n",
    "feature.shape,target.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "183d3a95-8f3b-48eb-97ec-e0777942d7ce",
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.model_selection import train_test_split\n",
    "x_train,x_test,y_train,y_test=train_test_split(feature,target,test_size=0.2,random_state=2021)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "d63286d4-5c4f-4e57-a0b2-45ea277eed89",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<style>#sk-container-id-2 {\n",
       "  /* Definition of color scheme common for light and dark mode */\n",
       "  --sklearn-color-text: black;\n",
       "  --sklearn-color-line: gray;\n",
       "  /* Definition of color scheme for unfitted estimators */\n",
       "  --sklearn-color-unfitted-level-0: #fff5e6;\n",
       "  --sklearn-color-unfitted-level-1: #f6e4d2;\n",
       "  --sklearn-color-unfitted-level-2: #ffe0b3;\n",
       "  --sklearn-color-unfitted-level-3: chocolate;\n",
       "  /* Definition of color scheme for fitted estimators */\n",
       "  --sklearn-color-fitted-level-0: #f0f8ff;\n",
       "  --sklearn-color-fitted-level-1: #d4ebff;\n",
       "  --sklearn-color-fitted-level-2: #b3dbfd;\n",
       "  --sklearn-color-fitted-level-3: cornflowerblue;\n",
       "\n",
       "  /* Specific color for light theme */\n",
       "  --sklearn-color-text-on-default-background: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, black)));\n",
       "  --sklearn-color-background: var(--sg-background-color, var(--theme-background, var(--jp-layout-color0, white)));\n",
       "  --sklearn-color-border-box: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, black)));\n",
       "  --sklearn-color-icon: #696969;\n",
       "\n",
       "  @media (prefers-color-scheme: dark) {\n",
       "    /* Redefinition of color scheme for dark theme */\n",
       "    --sklearn-color-text-on-default-background: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, white)));\n",
       "    --sklearn-color-background: var(--sg-background-color, var(--theme-background, var(--jp-layout-color0, #111)));\n",
       "    --sklearn-color-border-box: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, white)));\n",
       "    --sklearn-color-icon: #878787;\n",
       "  }\n",
       "}\n",
       "\n",
       "#sk-container-id-2 {\n",
       "  color: var(--sklearn-color-text);\n",
       "}\n",
       "\n",
       "#sk-container-id-2 pre {\n",
       "  padding: 0;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 input.sk-hidden--visually {\n",
       "  border: 0;\n",
       "  clip: rect(1px 1px 1px 1px);\n",
       "  clip: rect(1px, 1px, 1px, 1px);\n",
       "  height: 1px;\n",
       "  margin: -1px;\n",
       "  overflow: hidden;\n",
       "  padding: 0;\n",
       "  position: absolute;\n",
       "  width: 1px;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-dashed-wrapped {\n",
       "  border: 1px dashed var(--sklearn-color-line);\n",
       "  margin: 0 0.4em 0.5em 0.4em;\n",
       "  box-sizing: border-box;\n",
       "  padding-bottom: 0.4em;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-container {\n",
       "  /* jupyter's `normalize.less` sets `[hidden] { display: none; }`\n",
       "     but bootstrap.min.css set `[hidden] { display: none !important; }`\n",
       "     so we also need the `!important` here to be able to override the\n",
       "     default hidden behavior on the sphinx rendered scikit-learn.org.\n",
       "     See: https://github.com/scikit-learn/scikit-learn/issues/21755 */\n",
       "  display: inline-block !important;\n",
       "  position: relative;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-text-repr-fallback {\n",
       "  display: none;\n",
       "}\n",
       "\n",
       "div.sk-parallel-item,\n",
       "div.sk-serial,\n",
       "div.sk-item {\n",
       "  /* draw centered vertical line to link estimators */\n",
       "  background-image: linear-gradient(var(--sklearn-color-text-on-default-background), var(--sklearn-color-text-on-default-background));\n",
       "  background-size: 2px 100%;\n",
       "  background-repeat: no-repeat;\n",
       "  background-position: center center;\n",
       "}\n",
       "\n",
       "/* Parallel-specific style estimator block */\n",
       "\n",
       "#sk-container-id-2 div.sk-parallel-item::after {\n",
       "  content: \"\";\n",
       "  width: 100%;\n",
       "  border-bottom: 2px solid var(--sklearn-color-text-on-default-background);\n",
       "  flex-grow: 1;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-parallel {\n",
       "  display: flex;\n",
       "  align-items: stretch;\n",
       "  justify-content: center;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  position: relative;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-parallel-item {\n",
       "  display: flex;\n",
       "  flex-direction: column;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-parallel-item:first-child::after {\n",
       "  align-self: flex-end;\n",
       "  width: 50%;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-parallel-item:last-child::after {\n",
       "  align-self: flex-start;\n",
       "  width: 50%;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-parallel-item:only-child::after {\n",
       "  width: 0;\n",
       "}\n",
       "\n",
       "/* Serial-specific style estimator block */\n",
       "\n",
       "#sk-container-id-2 div.sk-serial {\n",
       "  display: flex;\n",
       "  flex-direction: column;\n",
       "  align-items: center;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  padding-right: 1em;\n",
       "  padding-left: 1em;\n",
       "}\n",
       "\n",
       "\n",
       "/* Toggleable style: style used for estimator/Pipeline/ColumnTransformer box that is\n",
       "clickable and can be expanded/collapsed.\n",
       "- Pipeline and ColumnTransformer use this feature and define the default style\n",
       "- Estimators will overwrite some part of the style using the `sk-estimator` class\n",
       "*/\n",
       "\n",
       "/* Pipeline and ColumnTransformer style (default) */\n",
       "\n",
       "#sk-container-id-2 div.sk-toggleable {\n",
       "  /* Default theme specific background. It is overwritten whether we have a\n",
       "  specific estimator or a Pipeline/ColumnTransformer */\n",
       "  background-color: var(--sklearn-color-background);\n",
       "}\n",
       "\n",
       "/* Toggleable label */\n",
       "#sk-container-id-2 label.sk-toggleable__label {\n",
       "  cursor: pointer;\n",
       "  display: block;\n",
       "  width: 100%;\n",
       "  margin-bottom: 0;\n",
       "  padding: 0.5em;\n",
       "  box-sizing: border-box;\n",
       "  text-align: center;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 label.sk-toggleable__label-arrow:before {\n",
       "  /* Arrow on the left of the label */\n",
       "  content: \"▸\";\n",
       "  float: left;\n",
       "  margin-right: 0.25em;\n",
       "  color: var(--sklearn-color-icon);\n",
       "}\n",
       "\n",
       "#sk-container-id-2 label.sk-toggleable__label-arrow:hover:before {\n",
       "  color: var(--sklearn-color-text);\n",
       "}\n",
       "\n",
       "/* Toggleable content - dropdown */\n",
       "\n",
       "#sk-container-id-2 div.sk-toggleable__content {\n",
       "  max-height: 0;\n",
       "  max-width: 0;\n",
       "  overflow: hidden;\n",
       "  text-align: left;\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-toggleable__content.fitted {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-toggleable__content pre {\n",
       "  margin: 0.2em;\n",
       "  border-radius: 0.25em;\n",
       "  color: var(--sklearn-color-text);\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-toggleable__content.fitted pre {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-2 input.sk-toggleable__control:checked~div.sk-toggleable__content {\n",
       "  /* Expand drop-down */\n",
       "  max-height: 200px;\n",
       "  max-width: 100%;\n",
       "  overflow: auto;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 input.sk-toggleable__control:checked~label.sk-toggleable__label-arrow:before {\n",
       "  content: \"▾\";\n",
       "}\n",
       "\n",
       "/* Pipeline/ColumnTransformer-specific style */\n",
       "\n",
       "#sk-container-id-2 div.sk-label input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-label.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Estimator-specific style */\n",
       "\n",
       "/* Colorize estimator box */\n",
       "#sk-container-id-2 div.sk-estimator input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-estimator.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-label label.sk-toggleable__label,\n",
       "#sk-container-id-2 div.sk-label label {\n",
       "  /* The background is the default theme color */\n",
       "  color: var(--sklearn-color-text-on-default-background);\n",
       "}\n",
       "\n",
       "/* On hover, darken the color of the background */\n",
       "#sk-container-id-2 div.sk-label:hover label.sk-toggleable__label {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "/* Label box, darken color on hover, fitted */\n",
       "#sk-container-id-2 div.sk-label.fitted:hover label.sk-toggleable__label.fitted {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Estimator label */\n",
       "\n",
       "#sk-container-id-2 div.sk-label label {\n",
       "  font-family: monospace;\n",
       "  font-weight: bold;\n",
       "  display: inline-block;\n",
       "  line-height: 1.2em;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-label-container {\n",
       "  text-align: center;\n",
       "}\n",
       "\n",
       "/* Estimator-specific */\n",
       "#sk-container-id-2 div.sk-estimator {\n",
       "  font-family: monospace;\n",
       "  border: 1px dotted var(--sklearn-color-border-box);\n",
       "  border-radius: 0.25em;\n",
       "  box-sizing: border-box;\n",
       "  margin-bottom: 0.5em;\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-estimator.fitted {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "/* on hover */\n",
       "#sk-container-id-2 div.sk-estimator:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-2 div.sk-estimator.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Specification for estimator info (e.g. \"i\" and \"?\") */\n",
       "\n",
       "/* Common style for \"i\" and \"?\" */\n",
       "\n",
       ".sk-estimator-doc-link,\n",
       "a:link.sk-estimator-doc-link,\n",
       "a:visited.sk-estimator-doc-link {\n",
       "  float: right;\n",
       "  font-size: smaller;\n",
       "  line-height: 1em;\n",
       "  font-family: monospace;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  border-radius: 1em;\n",
       "  height: 1em;\n",
       "  width: 1em;\n",
       "  text-decoration: none !important;\n",
       "  margin-left: 1ex;\n",
       "  /* unfitted */\n",
       "  border: var(--sklearn-color-unfitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-unfitted-level-1);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link.fitted,\n",
       "a:link.sk-estimator-doc-link.fitted,\n",
       "a:visited.sk-estimator-doc-link.fitted {\n",
       "  /* fitted */\n",
       "  border: var(--sklearn-color-fitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-fitted-level-1);\n",
       "}\n",
       "\n",
       "/* On hover */\n",
       "div.sk-estimator:hover .sk-estimator-doc-link:hover,\n",
       ".sk-estimator-doc-link:hover,\n",
       "div.sk-label-container:hover .sk-estimator-doc-link:hover,\n",
       ".sk-estimator-doc-link:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "div.sk-estimator.fitted:hover .sk-estimator-doc-link.fitted:hover,\n",
       ".sk-estimator-doc-link.fitted:hover,\n",
       "div.sk-label-container:hover .sk-estimator-doc-link.fitted:hover,\n",
       ".sk-estimator-doc-link.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "/* Span, style for the box shown on hovering the info icon */\n",
       ".sk-estimator-doc-link span {\n",
       "  display: none;\n",
       "  z-index: 9999;\n",
       "  position: relative;\n",
       "  font-weight: normal;\n",
       "  right: .2ex;\n",
       "  padding: .5ex;\n",
       "  margin: .5ex;\n",
       "  width: min-content;\n",
       "  min-width: 20ex;\n",
       "  max-width: 50ex;\n",
       "  color: var(--sklearn-color-text);\n",
       "  box-shadow: 2pt 2pt 4pt #999;\n",
       "  /* unfitted */\n",
       "  background: var(--sklearn-color-unfitted-level-0);\n",
       "  border: .5pt solid var(--sklearn-color-unfitted-level-3);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link.fitted span {\n",
       "  /* fitted */\n",
       "  background: var(--sklearn-color-fitted-level-0);\n",
       "  border: var(--sklearn-color-fitted-level-3);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link:hover span {\n",
       "  display: block;\n",
       "}\n",
       "\n",
       "/* \"?\"-specific style due to the `<a>` HTML tag */\n",
       "\n",
       "#sk-container-id-2 a.estimator_doc_link {\n",
       "  float: right;\n",
       "  font-size: 1rem;\n",
       "  line-height: 1em;\n",
       "  font-family: monospace;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  border-radius: 1rem;\n",
       "  height: 1rem;\n",
       "  width: 1rem;\n",
       "  text-decoration: none;\n",
       "  /* unfitted */\n",
       "  color: var(--sklearn-color-unfitted-level-1);\n",
       "  border: var(--sklearn-color-unfitted-level-1) 1pt solid;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 a.estimator_doc_link.fitted {\n",
       "  /* fitted */\n",
       "  border: var(--sklearn-color-fitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-fitted-level-1);\n",
       "}\n",
       "\n",
       "/* On hover */\n",
       "#sk-container-id-2 a.estimator_doc_link:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "#sk-container-id-2 a.estimator_doc_link.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-3);\n",
       "}\n",
       "</style><div id=\"sk-container-id-2\" class=\"sk-top-container\"><div class=\"sk-text-repr-fallback\"><pre>LinearRegression()</pre><b>In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. <br />On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.</b></div><div class=\"sk-container\" hidden><div class=\"sk-item\"><div class=\"sk-estimator fitted sk-toggleable\"><input class=\"sk-toggleable__control sk-hidden--visually\" id=\"sk-estimator-id-2\" type=\"checkbox\" checked><label for=\"sk-estimator-id-2\" class=\"sk-toggleable__label fitted sk-toggleable__label-arrow fitted\">&nbsp;&nbsp;LinearRegression<a class=\"sk-estimator-doc-link fitted\" rel=\"noreferrer\" target=\"_blank\" href=\"https://scikit-learn.org/1.5/modules/generated/sklearn.linear_model.LinearRegression.html\">?<span>Documentation for LinearRegression</span></a><span class=\"sk-estimator-doc-link fitted\">i<span>Fitted</span></span></label><div class=\"sk-toggleable__content fitted\"><pre>LinearRegression()</pre></div> </div></div></div></div>"
      ],
      "text/plain": [
       "LinearRegression()"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 导入线性回归算法模型的工具类\n",
    "from sklearn.linear_model import LinearRegression\n",
    "linner = LinearRegression()\n",
    "linner.fit(x_train,y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "e9f6a38f-3956-4471-b212-bb7e1449838b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([   0.85571906, -231.68204783,  545.36138163,  249.10354841,\n",
       "       -378.06043745,  181.31250825,  -69.86576245,  150.70716096,\n",
       "        572.99446991,   90.57901641])"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "linner.coef_  # 返回每一个维度的特征权重系数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "88a2c324-88af-46fd-88ac-ade0ba9b2f5b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "np.float64(149.69026652453022)"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "linner.intercept_ # 截距"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "45dc0c60-6fc2-452a-a070-7376d7ea3094",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.5235965273833811"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "linner.score(x_test,y_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "59c5d380-8d28-4fd1-9d9f-ba9296a1d26c",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([152.41908892, 184.49996045, 158.30989712, 166.84490815,\n",
       "        77.58679257,  53.82281941, 174.67553192, 176.11420688,\n",
       "       126.15315972,  86.01482775, 182.45574769, 122.92420721,\n",
       "       120.66688841, 171.82955734, 157.89536902, 119.28078147,\n",
       "       151.87569262, 155.67040189, 165.87327627, 189.22643018,\n",
       "        74.80265004, 144.24977815, 163.20616224,  56.08243813,\n",
       "       249.57207171, 247.53780378, 135.69491307, 194.53140382,\n",
       "       115.29796611, 150.39384167, 166.97665846, 115.80105473,\n",
       "       145.15284972, 154.63989864, 121.54243085, 121.72434031,\n",
       "       152.83884705, 199.93217924, 173.05117088, 228.85860588,\n",
       "       233.88539081, 179.71844596, 162.11037488, 124.09177599,\n",
       "        89.16085671, 205.18451733, 119.72931595,  84.03743806,\n",
       "       164.07749093, 111.47683935,  82.10744311, 202.87308278,\n",
       "        76.40932717, 118.11866829, 147.65236695, 223.87679959,\n",
       "       198.24277521, 132.67501457, 196.23903736, 234.09312533,\n",
       "       189.69969535, 180.29213805,  74.43716052,  79.62683358,\n",
       "        83.76704242,  67.66326512, 282.81451047, 198.25085148,\n",
       "        86.41844852, 261.88501333, 255.82547531, 208.79654739,\n",
       "       177.92231562,  89.5765181 , 169.74318142, 122.07224659,\n",
       "        85.13371893, 210.44499876, 102.86445494, 220.73489535,\n",
       "       222.53993351, 102.94297521, 184.37114061, 191.5860125 ,\n",
       "       135.31954814,  75.25917291,  87.07506279, 159.07172415,\n",
       "       114.17622697])"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "linner.predict(x_test)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b207257f-33d1-4e82-ae9a-de4ad27889a1",
   "metadata": {},
   "source": [
    "# 回归模型的评价指标\n",
    "- 回归类算法的模型评估一直都是回归算法的一个难点，回归类与分类算法的模型评估其实是相似的法则一 一找真实标签和预测值的差异。只不过在分类型算法中，这个差异只有一种角度来评判，那就是是否预测到了正确的分类，而在我们的回归类算法中，我们有两种不同的角度来看待回归的效果：\n",
    "  - 第一，我们是否预测到了正确或者接近正确的数值(因为误差的存在)\n",
    "  - 第二，我们是否拟合到了足够的信息。（是否模型预测的结果线性和样本真实的结果的线性更吻合）\n",
    "    - 这两种角度，分别对应着不同的模型评估指标"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "913d6ca5-9087-4796-b06a-a3d5663286bb",
   "metadata": {},
   "source": [
    "## 是否预测到了正确的数值\n",
    "- 回忆一下我们的RSS残差平方和，它的本质是我们的预测值与真实值之间的差异，也就是从一种角度来评估我们回归的效力，所以RSS既是我们的损失函数，也是我们回归类模型的模型评估指标之一，但是，RSS有着致命的缺点：它是一个无界的和，可以无限的大或者无限的小。我们只知道，我们想要求解的最小RSS，从RSS的公式来看，他不能为负，所以RSS越接近0越好，但是我们没有一个概念，究竟多小才算好，多接近0才算好，为了应对这种状况，sklearn中使用RSS的变体，均方差MSE(mean squared error)来均衡我们的预测值和真实值的差异\n",
    "\n",
    "$$MSE=\\frac{1}{m} \\sum_{i=1}^{m}{(y_i-\\widehat{y})^2}$$"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "df6c64ae-f519-4b84-84da-61deb5e9c1e7",
   "metadata": {},
   "source": [
    "- 均方差，本质是在RSS的基础上除以样本总量，得到了每个样本量上的平均误差。有了平均误差，我们就可以将平均误差和和我们的标签的取值范围（最大值和最小值）在一起比较，以此获得一个较为可靠的评估依据。(查看这个错误有多严重)\n",
    "  - 因为标签的最大值和最小值可以表示标签的一个分布情况，那么将其最大值和最小值的平均误差比较就可以大概看出在每个样本上的误差或者错误有多严重"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0652f597-83a3-4def-9f8f-8bfc4064e4cf",
   "metadata": {},
   "source": [
    "- 在sklearn当中，我们有两种方式调用这个评估指标：\n",
    "  - 一种是使用sklearn专用的模型评估模块metics里的类mean_squared_error\n",
    "  - 另一种是调用交叉验证的类cross_val_score并使用里面的scoring参数来设置为：neg_mean_squared_error使用均方差"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "7c0c6e87-cbc5-4ed8-8866-0f3afcadc24d",
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.linear_model import LinearRegression\n",
    "from sklearn.model_selection import train_test_split\n",
    "import sklearn.datasets as datasets\n",
    "from sklearn.metrics import mean_squared_error as MSE\n",
    "data = datasets.load_diabetes()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "891b7f31-7ff8-4394-abb4-c55e6ba2284c",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "((442, 10), (442,))"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "feature = data['data']\n",
    "target = data['target']\n",
    "feature.shape,target.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "id": "dbab9d54-31c5-42c5-8bd1-0b64a0147793",
   "metadata": {},
   "outputs": [],
   "source": [
    "x_train,x_test,y_train,y_test=train_test_split(feature,target,test_size=0.1,random_state=2022)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "id": "b86a688e-6f60-4005-a753-3a52cde28de6",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "np.float64(2391.59964637916)"
      ]
     },
     "execution_count": 39,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "linner = LinearRegression()\n",
    "linner.fit(x_train,y_train)\n",
    "y_pred = linner.predict(x_test)\n",
    "MSE(y_test,y_pred)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "id": "aa4fc568-c726-4067-a93c-6f7562af7853",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(np.float64(39.0), np.float64(317.0))"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y_test.min(),y_test.max()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "727577d3-3ad9-4a04-9021-881629d74732",
   "metadata": {},
   "source": [
    "- 交叉验证求得的均方误差\n",
    "  - 均方误差的计算公式中求得的均方误差的值不可能为负。但是sklearn中的参数scoring下，均方误差作为评判标准时，却是计算负均方误差(neg_mean_squared_error)。这是因为sklearn在计算模型评估的时候会考虑指标的性质，均方误差本身是一种误差，所以被sklearn划分为模型的一种损失(loss)。在sklearn中，所有的损失都是用负数表示，因此均方误差也被显示为负数，真正的均方误差MSE的数值，其实就是neg_mean_squared_error去掉负号的数字。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "id": "0ff543ce-f442-49c6-9c95-7bae26caa18b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([-3146.87931287, -3453.39532622, -3163.68076881, -3186.10266521,\n",
       "       -2737.42453223])"
      ]
     },
     "execution_count": 44,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.model_selection import cross_val_score\n",
    "linner = LinearRegression()\n",
    "cross_val_score(linner,x_train,y_train,cv=5,scoring='neg_mean_squared_error')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bab8fe7f-45be-49e1-978a-bc03262753cf",
   "metadata": {},
   "source": [
    "- 绝对值误差（了解）\n",
    "  - 除了MSE,我们还有与MSE类似的MAE(Mean absolute error,绝对均值误差)：\n",
    "  - $$MSE=\\frac{1}{m} \\sum_{i=1}^{m}{|(y_i-\\widehat{y})|}$$\n",
    "  - 其表达的概念与均方误差完全一致，不给过在真实标签和预测值之间的差异外我们使用的是L1范式(绝对值)。现实使用中，MSE和MAE选一个来使用就好。\n",
    "    - 在sklearn当中，我们使用:\n",
    "      - from sklearn.metrics import mean_absolut_error来调用MAE\n",
    "    - 同时，我们也可以使用交叉验证中的"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "44922e31-3834-4dce-a41e-a9117344ac7d",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
